//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __TLSMANAGER_H__
#define __TLSMANAGER_H__

#include <elasys_server.h>
#include <linknode.h>

class CTlsZone : public DLinkNode
{
public:
    void GetValue(
        /* [in] */ Int32 index,
        /* [out] */ PVoid * ppValue);

    void SetValue(
        /* [in] */ Int32 index,
        /* [in] */ PVoid pValue);
public:
    CTlsZone();
    CTlsZone(CTlsZone * pTlsZone);

    PVoid m_tlsValue[TLS_TOTAL_SLOTS];
};

class CTlsManager
{
public:
    ECode AcquireSlot(
        /* [in] */ ThreadLocalSlotType type,
        /* [out] */ Int32 * pSlotIndex);

    ECode RelinquishSlot(
        /* [in] */ Int32 slotIndex,
        /* [out] */ BufferOf<Int32> * pUsedPtrs);

    ECode CleanupSlot(
        /* [in] */ Int32 slotIndex,
        /* [out] */ BufferOf<Int32> * pUsedPtrs);

    ECode GetSlotValue(
        /* [in] */ ThreadLocalSlotType type,
        /* [in] */ Int32 slotIndex,
        /* [out] */ PVoid * ppValue);

    ECode SetSlotValue(
        /* [in] */ ThreadLocalSlotType type,
        /* [in] */ Int32 slotIndex,
        /* [in] */ PVoid pValue);

public:
    CTlsManager();
    ~CTlsManager();

    ECode Constructor();

    void AttachTlsZone(CTlsZone * pTls);
    void DetachTlsZone(CTlsZone * pTls);

private:
    PVoid m_hLock;
    Int32 m_slotType[TLS_TOTAL_SLOTS];
    DLinkNode m_tlsZoneList;
};

inline
CTlsZone::CTlsZone()
{
    memset((void *)m_tlsValue, 0, sizeof(m_tlsValue));
}

inline
CTlsZone::CTlsZone(CTlsZone * pTlsZone)
{
    memset((void *)m_tlsValue, 0, sizeof(m_tlsValue));
    m_tlsValue[TL_CALLBACK_SLOT] = pTlsZone->m_tlsValue[TL_CALLBACK_SLOT];
    m_tlsValue[TL_APPLET_SLOT]   = pTlsZone->m_tlsValue[TL_APPLET_SLOT];
    m_tlsValue[TL_DOMAIN_SLOT]   = pTlsZone->m_tlsValue[TL_DOMAIN_SLOT];
}

#endif //!(__TLSMANAGER_H__)

